#include "image_viewer.h"


#include <QGraphicsScene>  // 用于管理图片场景
#include <QGraphicsPixmapItem>  // 用于管理图片项目
#include <QFileInfo>  // 用于检查文件是否存在
#include <QMessageBox>  // 用于显示警告信息

#include <cstdint>  // 包含 uint8_t 和 uint16_t 的定义


namespace isp_tuning {

image_viewer::image_viewer(QObject* parent) : QObject(parent) {
    // 初始化图片显示控件
    view = new QGraphicsView();  // 创建 QGraphicsView
    QGraphicsScene* scene = new QGraphicsScene(view);  // 创建 QGraphicsScene，并将 view 作为父对象
    view->setScene(scene);  // 将 scene 设置到 view 中

    // 初始化 imageItem
    imageItem = new QGraphicsPixmapItem();  // 创建 QGraphicsPixmapItem
    scene->addItem(imageItem);  // 将 imageItem 添加到 scene 中

}




QGraphicsView* image_viewer::get_view() {
    return view;  // 返回 view 对象
}





bool image_viewer::display_image() {
    // 获取 param_manager 的单例实例
    param_manager* manager = param_manager::getInstance();

    // 从param_manager读取数据
    RawMetadata metadata = manager->get_raw_metadata();
    QString file_path = manager->get_file_path();

    if (!QFileInfo::exists(file_path)) {
        QMessageBox::warning(nullptr, "Error", "File does not exist!");  // 如果文件不存在，显示错误信息
        return false;
    }

    // 加载 RAW 文件
    QByteArray raw_data;
    if (!load_raw_image(file_path, raw_data, metadata)) {
        QMessageBox::warning(nullptr, "Error", "Failed to load RAW image!");  // 如果加载失败，显示错误信息
        return false;
    }

    // 将 RAW 数据转换为 RGB 图像
    QImage image = raw2clor(raw_data, metadata);

    // 显示图像
    if (image.isNull()) {
        QMessageBox::warning(nullptr, "Error", "Failed to convert RAW image!");
        return false;
    }
    // 将图像显示在ui界面上
    // 将 QImage 转换为 QPixmap
    QPixmap pixmap = QPixmap::fromImage(image);

    // 设置图片到 imageItem
    imageItem->setPixmap(pixmap);

    // 自适应显示图片
    view->fitInView(imageItem, Qt::KeepAspectRatio);

    return true;  // 返回 true 表示操作成功
}



// 把raw图片加载进内存
bool image_viewer::load_raw_image(const QString& file_path, QByteArray& raw_data, const RawMetadata& metadata){
    // 打开RAW文件 并读取 RAW 文件数据。
    QFile file(file_path);
    if (!file.open(QIODevice::ReadOnly)) {
        return false;
    }
    raw_data = file.readAll();
    file.close();

    // 检查文件大小是否与元数据匹配
    qint64 expectedSize = metadata.width * metadata.height * 2;  // 每个像素 2 字节

    if (raw_data.size() != expectedSize) {
        QMessageBox::warning(nullptr, "Error", "File size does not match the width and height!");
        return false;
    }

    qDebug() << "raw image loaded successfully!";

    return true;
}


QImage image_viewer::raw2clor(const QByteArray& raw_data, const RawMetadata& metadata) {
    // 创建 QImage 对象，用于存储处理后的图像
    QImage image(metadata.width, metadata.height, QImage::Format_RGB888);

    // 获取元数据
    int offset = metadata.sensorBits - 8;  // 位宽偏移量
    int pattern = metadata.bayerPattern;   // Bayer 模式

    // 将 RAW 数据转换为 u16 数组
    const uint16_t* bayer_data = reinterpret_cast<const uint16_t*>(raw_data.constData());

    // 遍历每个像素
    for (int row = 0; row < metadata.height; row++) {
        for (int col = 0; col < metadata.width; col++) {
            // 计算当前像素的 Bayer 通道
            uint8_t pixel_channel = static_cast<uint8_t>((((row & 1) << 1) + (col & 1)) ^ pattern);

            // 获取像素值并调整位宽
            int pixel_value = bayer_data[row * metadata.width + col] >> offset;
            pixel_value = qBound(0, pixel_value, 255);  // 钳位到 [0, 255]

            // 根据 Bayer 通道设置像素颜色
            if (pixel_channel == 0) {  // R 通道
                image.setPixel(col, row, qRgb(pixel_value, 0, 0));
            } else if (pixel_channel == 1 || pixel_channel == 2) {  // G 通道
                image.setPixel(col, row, qRgb(0, pixel_value, 0));
            } else {  // B 通道
                image.setPixel(col, row, qRgb(0, 0, pixel_value));
            }
        }
    }
    qDebug() << "raw2clor successfully!";
    return image;
}



} // namespace isp_tunning
